#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
'''
@File    :   Person.py
@Time    :   2020/11/06
@Author  :   wenke wang
@Version :   1.0
@Desc    :   病人信息
'''

# here put the import lib
from datetime import datetime as dat, timedelta
from decimal import Decimal
from config import Gender, Pal

class Person():
    """
    人的信息
    """
    def __init__(self, gender, birth, height, weight, pal):        
        self.__gender = self.__parsegender(gender)
        self.__birth = birth
        self.__age = self.__getage(birth)
        self.__height = Decimal(str(height))
        self.__weight = Decimal(str(weight))
        self.__pal = self.__parsepal(pal)

    def __parsegender(self, gender):
        isvalid, g = Gender.isvalidvalue(gender, return_gender_if_valid=True)
        if not isvalid:
            raise ValueError("%s is not a valida Gender value." % str(gender))
        return g

    def __parsebirth(self, birth):
        try:
            birthday = dat.strptime(birth, "%Y-%m-%d")            
            return True, birthday
        except Exception as e:
            return False, None

    def __getage(self, birth):
        isvalid, birthday = self.__parsebirth(birth)
        if not isvalid:
            raise ValueError("%s is not a valid birthday, it's format like 'YYYY-MM-DD'." % birth)
        age = int((dat.today() - birthday).days / 365)
        if age < 0:
            raise ValueError("%s is not a valid birthday" % birth)
        return age

    def __parsepal(self, pal):
        isvalid, p = Pal.isvalidvalue(pal, return_pal_if_valid=True)
        if not isvalid:
            raise ValueError("%s is not a valid Pal value." % str(pal))
        return p

    @property
    def gender(self):
        return self.__gender
    @gender.setter
    def gender(self, value):
        self.__gender = self.__parsegender(value)
    
    @property
    def birth(self):
        return self.__birth
    @birth.setter
    def birth(self, value):
        self.__birth = value
        self.__age = self.__getage(value)
    
    @property
    def age(self):
        return self.__age
    
    @property
    def height(self):
        return self.__height
    @height.setter
    def height(self, value):
        self.__height = Decimal(str(value))
    
    @property
    def weight(self):
        return self.__weight
    @weight.setter
    def weight(self, value):
        self.__weight = Decimal(str(value))

    @property
    def pal(self):
        return self.__pal
    @pal.setter
    def pal(self, value):
        self.__pal = self.__parsepal(value)

    @property
    def normal_ree(self):
        """
        使用简便公式计算的BEE/REE
        """
        t = Decimal(Decimal("10.0") * self.weight + Decimal("6.25") * self.height - Decimal("5.0") * Decimal(self.age))
        return int(t + Decimal("5.0") if self.gender == Gender.M else t - Decimal("161.0"))

    @property
    def classic_ree(self):
        """
        使用经典公式计算BEE/REE
        """
        t = Decimal("9.99") * self.weight + Decimal("6.25") * self.height - Decimal("4.92") * Decimal(self.age)
        return int(t + Decimal("5.0") if self.gender == Gender.M else t - Decimal("161.0"))

    def validate(self):
        """
        校验人的信息
        """
        if self.age < 6:
            raise ValueError("Age could not less than 6 year's old.")
        
        if self.age > 79 and self.pal == Pal.SEVERE:
            raise ValueError("Could not got the PAL's value when age great than 79 year's old.")
        
        zero = Decimal("0")
        neg_one = Decimal("-1")
        # 0 >= height
        if zero.compare(self.height) != neg_one:
            raise ValueError("Height could not less than 1cm.")
        # 0 >= weight
        if zero.compare(self.weight) != neg_one:
            raise ValueError("Weight could not less than 1kg.")